package com.imis.module.system.bus;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.enums.ArgumentResponseEnum;
import com.imis.base.globle.response.BaseResponse;
import com.imis.base.globle.response.CommonResponse;
import com.imis.base.util.ConvertUtils;
import com.imis.module.base.BaseBus;
import com.imis.module.system.model.converter.SysDictConverter;
import com.imis.module.system.model.po.SysDict;
import com.imis.module.system.model.po.SysDictItem;
import com.imis.module.system.model.ro.*;
import com.imis.module.system.model.vo.SysDictItemVO;
import com.imis.module.system.model.vo.SysDictVO;
import com.imis.module.system.service.ISysDictItemService;
import com.imis.module.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 字典项 业务处理类
 * </p>
 *
 * @author XinLau
 * @since 2020-03-23
 */
@Service
public class SysDictBus extends BaseBus {

    /**
     * 字典项 服务类
     */
    private ISysDictService serviceBySysDictService;

    @Autowired
    public void setServiceBySysDictService(ISysDictService serviceBySysDictService) {
        this.serviceBySysDictService = serviceBySysDictService;
    }

    /**
     * 字典值 服务类
     */
    private ISysDictItemService serviceBySysDictItemService;

    @Autowired
    public void setServiceBySysDictItemService(ISysDictItemService serviceBySysDictItemService) {
        this.serviceBySysDictItemService = serviceBySysDictItemService;
    }

    /**
     * 添加字典项校验
     *
     * @param sysDictAdd - 字典项添加对象
     * @return SysDict - 字典项
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDict dictAddVerification(SysDictAddRO sysDictAdd) {
        SysDict sysDict = this.serviceBySysDictService.queryDictByName(sysDictAdd.getDictName());
        // 字典项名称 - 判断是否重复添加
        if (ConvertUtils.isNotEmpty(sysDict)) {
            ArgumentResponseEnum.DICT_ADD_ERR_NAME_REPEAT.assertIsTrue(CommonConstant.DEL_FLAG_NOT_DELETE.equals(sysDict.getDelFlag()), sysDictAdd.getDictName());
            ArgumentResponseEnum.DICT_ADD_ERR_NAME_DELETE.assertIsNull(sysDict, sysDictAdd.getDictName());
        }
        sysDict = this.serviceBySysDictService.queryDictByCode(sysDictAdd.getDictCode());
        // 字典项编码 - 判断是否重复添加
        if (ConvertUtils.isNotEmpty(sysDict)) {
            ArgumentResponseEnum.DICT_ADD_ERR_CODE_DELETE.assertIsTrue(CommonConstant.DEL_FLAG_NOT_DELETE.equals(sysDict.getDelFlag()), sysDictAdd.getDictCode());
            ArgumentResponseEnum.DICT_ADD_ERR_CODE_DELETE.assertIsNull(sysDict, sysDictAdd.getDictCode());
        }
        return SysDictConverter.INSTANCE.getAddEntity(sysDictAdd);
    }

    /**
     * 删除字典项校验
     *
     * @param dictIdentification - 字典项编号
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDict dictDeleteVerification(final Long dictIdentification) {
        SysDict sysDict = this.serviceBySysDictService.getById(dictIdentification);
        // 1.根据字典项信息查询，该字典项不存在
        ArgumentResponseEnum.DICT_DELETE_ERR_NON.assertNotNull(sysDict, dictIdentification);
        // 2.判断字典项是否使用
        List<SysDictItem> sysDictItemList = this.serviceBySysDictItemService.selectSysDictItemListByDictId(sysDict.getId());
        ArgumentResponseEnum.DICT_DELETE_ERR_USE.assertIsNull(sysDictItemList, sysDict.getDictName());
        return sysDict;
    }

    /**
     * 更新字典项校验
     *
     * @param sysDictUpdate - 字典项修改对象
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDict dictUpdateVerification(SysDictUpdateRO sysDictUpdate) {
        SysDict sysDict = this.serviceBySysDictService.getById(sysDictUpdate.getId());
        // 1.根据字典项信息查询，该字典项不存在
        ArgumentResponseEnum.DICT_UPDATE_ERR_NON.assertNotNull(sysDict, sysDictUpdate.getId());
        // 2.校验字典项名重复
        if (!sysDict.getDictName().equals(sysDictUpdate.getDictName())) {
            // 前端传递字典项名与数据库查询出来的不一致做字典项名重复校验（字典项名修改做校验）
            SysDict sysDictByDictName = this.serviceBySysDictService.queryDictByName(sysDictUpdate.getDictName());
            // 根据字典项名查询，判断字典项名存在
            ArgumentResponseEnum.DICT_UPDATE_ERR_NAME_REPEAT.assertIsNull(sysDictByDictName, sysDictUpdate.getDictName());
        }
        // 3.字典项编码重复校验
        if (!sysDict.getDictCode().equals(sysDictUpdate.getDictCode())) {
            SysDict sysDictByDictCode = this.serviceBySysDictService.queryDictByCode(sysDictUpdate.getDictCode());
            // 根据字典项编码查询，判断字典项编码存在
            ArgumentResponseEnum.DICT_UPDATE_ERR_CODE_REPEAT.assertIsNull(sysDictByDictCode, sysDictUpdate.getDictCode());
        }
        // 4.生成更新对象
        SysDictConverter.INSTANCE.getUpdateEntity(sysDict, sysDictUpdate);
        return sysDict;
    }

    /**
     * 添加字典值校验
     *
     * @param sysDictItemAdd - 字典值添加对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDictItem dictItemAddVerification(SysDictItemAddRO sysDictItemAdd) {
        SysDictItem sysDictItem = this.serviceBySysDictItemService.selectDictItemByTextAndDict(sysDictItemAdd.getItemText(), sysDictItemAdd.getDictId());
        if (ConvertUtils.isNotEmpty(sysDictItem)) {
            // 根据字典值信息查询，判断字典值被停用 状态（1启用 0不启用）
            ArgumentResponseEnum.DICT_ADD_ERR_NAME_REPEAT.assertIsTrue(CommonConstant.STATUS_ERR.equals(sysDictItem.getStatus()), sysDictItemAdd.getItemText());
            // 根据字典项信息查询，判断字典项存在
            ArgumentResponseEnum.DICT_ITEM_ADD_ERR_TEXT_REPEAT.assertIsNull(sysDictItem, sysDictItemAdd.getItemText());
        }
        sysDictItem = this.serviceBySysDictItemService.selectDictItemByValueAndDict(sysDictItemAdd.getItemValue(), sysDictItemAdd.getDictId());
        if (ConvertUtils.isNotEmpty(sysDictItem)) {
            // 根据字典编码查询，判断字典值被停用 状态（1启用 0不启用）
            ArgumentResponseEnum.DICT_ADD_ERR_NAME_REPEAT.assertIsTrue(CommonConstant.STATUS_ERR.equals(sysDictItem.getStatus()), sysDictItemAdd.getItemValue());
            // 根据字典编码查询，判断字典编码存在
            ArgumentResponseEnum.DICT_ITEM_ADD_ERR_VALUE_REPEAT.assertIsNull(sysDictItem, sysDictItemAdd.getItemValue());
        }
        return SysDictConverter.INSTANCE.getAddEntity(sysDictItemAdd);
    }

    /**
     * 删除字典值校验
     *
     * @param dictItemIdentification - 字典值编号
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDictItem dictItemDeleteVerification(final Long dictItemIdentification) {
        SysDictItem sysDictItem = this.serviceBySysDictItemService.getById(dictItemIdentification);
        // 1.根据字典值信息查询，该字典值不存在
        ArgumentResponseEnum.DICT_ITEM_DELETE_ERR_NON.assertNotNull(sysDictItem, dictItemIdentification);
        // 2.判断字典值是否使用 TODO:This 判断字典值是否使用
        return sysDictItem;
    }

    /**
     * 更新字典值校验
     *
     * @param sysDictItemUpdate - 字典值修改对象
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private SysDictItem dictItemUpdateVerification(SysDictItemUpdateRO sysDictItemUpdate) {
        SysDictItem sysDictItem = this.serviceBySysDictItemService.getById(sysDictItemUpdate.getId());
        // 1.根据字典值信息查询，该字典值不存在
        ArgumentResponseEnum.DICT_ITEM_UPDATE_ERR_NON.assertNotNull(sysDictItem, sysDictItemUpdate.getItemText());
        // 2.校验字典值文本重复
        if (!sysDictItem.getItemText().equals(sysDictItemUpdate.getItemText())) {
            // 前端传递字典值文本与数据库查询出来的不一致做字典值文本重复校验（字典值修改做校验）
            SysDictItem sysDictByTextAndDict = this.serviceBySysDictItemService.selectDictItemByTextAndDict(sysDictItemUpdate.getItemText(), sysDictItem.getDictId());
            //  根据字典值文本和字典项查询，该字典值文本存在
            ArgumentResponseEnum.DICT_ITEM_UPDATE_ERR_TEXT_REPEAT.assertIsNull(sysDictByTextAndDict, sysDictItemUpdate.getItemText());
        }
        // 3.字典字典值值重复校验
        if (!sysDictItem.getItemValue().equals(sysDictItemUpdate.getItemValue())) {
            SysDictItem sysDictByValueAndDict = this.serviceBySysDictItemService.selectDictItemByValueAndDict(sysDictItemUpdate.getItemValue(), sysDictItem.getDictId());
            //  根据字典项字典值值字典项查询，该字典值值存在
            ArgumentResponseEnum.DICT_ITEM_UPDATE_ERR_VALUE_REPEAT.assertIsNull(sysDictByValueAndDict, sysDictItemUpdate.getItemText());
        }
        SysDictConverter.INSTANCE.getUpdateEntity(sysDictItem, sysDictItemUpdate);
        return sysDictItem;
    }

    /**
     * 分页查询字典项
     *
     * @param pagingQueryDictDTO - 字典项查询对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public CommonResponse<Page<SysDictVO>> pagingQuerySysDictListByParameter(final PagingQueryDictDTO pagingQueryDictDTO) {
        Page<SysDictVO> sysDictListByParameter = this.serviceBySysDictService.pagingQuerySysDictListByParameter(pagingQueryDictDTO);
        return new CommonResponse<>(sysDictListByParameter);
    }

    /**
     * 字典项添加接口
     *
     * @param sysDictAdd - 字典项添加对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse addDict(SysDictAddRO sysDictAdd) {
        // 1.校验字典项重复
        SysDict sysDict = this.dictAddVerification(sysDictAdd);
        boolean saveDict = this.serviceBySysDictService.saveDict(sysDict);
        // 2.判断保存成功
        ArgumentResponseEnum.DICT_ADD_ERR.assertIsTrue(saveDict, sysDictAdd.getDictName());
        return new CommonResponse<>();
    }

    /**
     * 字典项删除接口
     *
     * @param dictIdentification - 字典项标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse deleteDict(final Long dictIdentification) {
        // 1.删除字典项校验
        SysDict sysDict = this.dictDeleteVerification(dictIdentification);
        // 2.删除字典项
        boolean deleteDict = this.serviceBySysDictService.deleteDict(dictIdentification);
        // 3.判断删除成功
        ArgumentResponseEnum.DICT_ADD_ERR.assertIsTrue(deleteDict, sysDict.getDictName());
        // TODO:this 删除对应字典项的缓存
        return new CommonResponse<>();
    }

    /**
     * 字典项查看接口
     *
     * @param dictIdentification - 字典项标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public CommonResponse<SysDictVO> queryDictById(final Long dictIdentification) {
        SysDict sysDict = this.serviceBySysDictService.getById(dictIdentification);
        // 1.根据字典项信息查询，该字典项不存在
        ArgumentResponseEnum.DICT_QUERY_ERR.assertNotNull(sysDict, dictIdentification);
        return new CommonResponse<>(SysDictConverter.INSTANCE.getReturnValue(sysDict));
    }

    /**
     * 字典项更新接口
     *
     * @param sysDictUpdate - 字典项更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse updateDict(SysDictUpdateRO sysDictUpdate) {
        // 1.修改字典项校验
        SysDict sysDict = this.dictUpdateVerification(sysDictUpdate);
        // 2.字典项信息修改
        boolean updateDict = this.serviceBySysDictService.updateByDictIdentification(sysDict);
        // 3.判断保存成功
        ArgumentResponseEnum.DICT_ADD_ERR.assertIsTrue(updateDict, sysDictUpdate.getDictName());
        return new CommonResponse<>();
    }

    /**
     * 分页查询字典值
     *
     * @param pagingQueryDictItemDTO - 字典值查询对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public CommonResponse<Page<SysDictItemVO>> pagingQuerySysDictItemListByParameter(final PagingQueryDictItemDTO pagingQueryDictItemDTO) {
        Page<SysDictItemVO> sysDictItemListByParameter = this.serviceBySysDictItemService.pagingQuerySysDictItemListByParameter(pagingQueryDictItemDTO);
        return new CommonResponse<>(sysDictItemListByParameter);
    }

    /**
     * 根据字典项获取字典值
     *
     * @param dictIdentification - 字典项标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public CommonResponse<List<SysDictItemVO>> queryDictItemByDict(final Long dictIdentification) {
        // 字典项校验
        SysDict sysDict = this.serviceBySysDictService.getById(dictIdentification);
        // 1.根据字典项标识查询，该字典项不存在
        ArgumentResponseEnum.DICT_QUERY_ERR.assertNotNull(sysDict, dictIdentification);
        // 2.查询字典值
        List<SysDictItem> sysDictItemList = this.serviceBySysDictItemService.selectSysDictItemListByDictId(sysDict.getId());
        ArgumentResponseEnum.DICT_QUERY_ERR.assertIsNull(sysDictItemList, dictIdentification);
        return new CommonResponse(SysDictConverter.INSTANCE.getDictItemReturnValueList(sysDictItemList));
    }

    /**
     * 字典值添加接口
     *
     * @param sysDictItemAdd - 字典值添加对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse addDictItem(SysDictItemAddRO sysDictItemAdd) {
        // 1.校验字典项重复
        SysDictItem sysDictItem = this.dictItemAddVerification(sysDictItemAdd);
        // 2.创建新字典项
        boolean saveDictItem = this.serviceBySysDictItemService.saveDictItem(sysDictItem);
        // 3.判断保存成功
        ArgumentResponseEnum.DICT_ADD_ERR.assertIsTrue(saveDictItem, sysDictItemAdd.getItemText());
        return new CommonResponse<>();
    }

    /**
     * 字典值删除接口
     *
     * @param dictItemIdentification - 字典值标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse deleteDictItem(final Long dictItemIdentification) {
        // 删除字典值校验
        SysDictItem sysDictItem = this.dictItemDeleteVerification(dictItemIdentification);
        // 2.删除字典值
        boolean deleteDictItem = this.serviceBySysDictItemService.deleteDictItem(dictItemIdentification);
        // 3.判断删除成功
        ArgumentResponseEnum.DICT_DELETE_ERR.assertIsTrue(deleteDictItem, sysDictItem.getItemText());
        // TODO:this 删除对应字典值的缓存
        return new CommonResponse<>();
    }

    /**
     * 字典值查看接口
     *
     * @param dictItemIdentification - 字典值标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public CommonResponse<SysDictItemVO> queryDictItemById(final Long dictItemIdentification) {
        SysDictItem sysDictItem = this.serviceBySysDictItemService.getById(dictItemIdentification);
        // 1.根据字典值信息查询，该字典值不存在
        ArgumentResponseEnum.DICT_QUERY_ERR.assertNotNull(sysDictItem, dictItemIdentification);
        return new CommonResponse<>(SysDictConverter.INSTANCE.getReturnValue(sysDictItem));
    }

    /**
     * 字典值修改接口
     *
     * @param sysDictItemUpdate - 字典值更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 14:54
     */
    public BaseResponse updateDictItem(SysDictItemUpdateRO sysDictItemUpdate) {
        // 1.修改字典值校验
        SysDictItem sysDictItem = this.dictItemUpdateVerification(sysDictItemUpdate);
        // 2.字典值信息修改
        boolean updateDictItem = this.serviceBySysDictItemService.updateByDictItemIdentification(sysDictItem);
        // 3.判断保存成功
        ArgumentResponseEnum.DICT_ITEM_UPDATE_ERR.assertIsTrue(updateDictItem, sysDictItemUpdate.getItemText());
        return new CommonResponse<>();
    }

}